package service

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/json"
	"errors"

	"github.com/wzh200x/hyperNexus/hyperNexusProtocol/interfaceServerProtocol"
	"github.com/wzh200x/hyperNexus/hyperNexusType"
	Server "github.com/wzh200x/webServer/server"
)

// 微信相关服务函数
// 注意：配置信息已移至platformService.go

// 微信用户信息
type WxUserInfo struct {
	OpenID string `json:"openId"`
}

// 生成用户名（基于OpenID）
func GenerateUsername(platformType int, openID string) string {
	platformName := hyperNexusType.GetPlatformName(platformType)
	// 截取OpenID的一部分作为用户名
	if len(openID) > 64 {
		return platformName + "_" + openID[len(openID)-64:]
	}
	return platformName + "_" + openID
}

// GetWechatPlatformInfo 获取微信平台用户信息
// 返回第三方账号(openid)、会话密钥(session_key)和可能的错误
func GetPlatformInfo(platformType int32, appId string, appSecret string, privateKey string, publicKey string, packageName string, code string) (string, string, error) {
	// 从interfaceServer获取平台登录信息
	interfaceServerClient := Server.ServerApp.InterfaceServerClient.GetClientProxy()
	req := interfaceServerProtocol.LoginRequest{
		Platform:    platformType,
		AppId:       appId,
		AppSecret:   appSecret,
		PrivateKey:  privateKey,
		PublicKey:   publicKey,
		PackageName: packageName,
		Code:        code,
	}
	resp, err := interfaceServerClient.MiniGamePlatformLogin(req)
	if err != nil {
		return "", "", err
	}
	// 返回openid作为第三方账号和session_key作为会话密钥
	// Wechat平台返回的Datas字段为session_key
	return resp.OpenId, resp.Datas, nil
}

func WxDecrptData(appId string, sessionKey string, encryptedData string, iv string) (map[string]interface{}, error) {
	// 解密数据
	// 这里需要使用微信提供的解密函数
	// 解密后的数据为JSON字符串，包含用户信息
	// 解析JSON字符串获取用户信息
	// 返回用户信息
	// Base64 decode
	sessionKeyBytes, err := base64.StdEncoding.DecodeString(sessionKey)
	if err != nil {
		return nil, errors.New("session key base64 decode error")
	}

	cipherText, err := base64.StdEncoding.DecodeString(encryptedData)
	if err != nil {
		return nil, errors.New("encrypted data base64 decode error")
	}

	ivBytes, err := base64.StdEncoding.DecodeString(iv)
	if err != nil {
		return nil, errors.New("iv base64 decode error")
	}

	// AES-CBC decrypt
	block, err := aes.NewCipher(sessionKeyBytes)
	if err != nil {
		return nil, errors.New("aes cipher creation error")
	}

	if len(cipherText)%aes.BlockSize != 0 {
		return nil, errors.New("ciphertext is not a multiple of the block size")
	}

	mode := cipher.NewCBCDecrypter(block, ivBytes)
	mode.CryptBlocks(cipherText, cipherText)

	// Unpad
	plainText, err := unpad(cipherText)
	if err != nil {
		return nil, errors.New("unpad error: " + err.Error())
	}

	// JSON unmarshal
	var decrypted map[string]interface{}
	if err := json.Unmarshal(plainText, &decrypted); err != nil {
		return nil, errors.New("json unmarshal error")
	}

	return decrypted, nil
}

func unpad(s []byte) ([]byte, error) {
	if len(s) == 0 {
		return nil, errors.New("empty input")
	}
	padding := int(s[len(s)-1])
	if padding > len(s) {
		return nil, errors.New("padding size larger than input")
	}
	return s[:len(s)-padding], nil
}
